﻿/*
 * iec104master.cpp
 *
 *  Created on: 2017年3月20日
 *      Author: work
 */

#include <dm/export.hpp>

#define DM_API_PROTOCOL DM_API_EXPORT

#include <dm/protocol/iec104master.hpp>
#include <dm/os/log/logger.hpp>
#include <ctime>

namespace dm{
namespace protocol{

static const char* logModule = "CIec104Master.protocol.dm";

CIec104Master::CIec104Master():CIec104(){
	log().debug(THISMODULE "创建对象");
	setAutoStatrtDt(true);
}

CIec104Master::~CIec104Master(){
	log().debug(THISMODULE "销毁对象");
}

CIec104Master::EAction CIec104Master::dealStopDt( const ts_t& /*ts*/,const rts_t& /*rts*/ ){
	log().debug(THISMODULE "停止链路传输,主站不支持");

	return Action_Nothing;
}

CIec104Master::EAction CIec104Master::dealStopDtConf( const ts_t& /*ts*/,const rts_t& rts ){
	log().debug(THISMODULE "停止链路传输确认");
	m_dtStarted = false;
	m_lastConffedTime = rts;
	m_lastSendConfirmTime = m_lastConffedTime;

	return Action_Nothing;
}

CIec104Master::EAction CIec104Master::dealStartDt( const ts_t& /*ts*/,const rts_t& /*rts*/ ){
	log().debug(THISMODULE "开启数据传输,不支持");

	return Action_Nothing;
}

CIec104Master::EAction CIec104Master::dealStartDtConf( const ts_t& /*ts*/,const rts_t& /*rts*/ ){
	log().debug(THISMODULE "启动链路传输确认");
	m_dtStarted = true;
	m_ifStartingDt = false;
	return Action_Nothing;
}

/**
 * 状态量
 * @param rf
 * @param tf
 * @return
 */
CIec104Master::EAction CIec104Master::dealAsdu_M_DP_NA_1( const frame_apdu_t& rf,frame_apdu_t& /*tf*/,const ts_t& ts,const rts_t& rts ){
	dm::uint8 count = rf.getElementsCount();
	for( dm::uint8 i=0;i<count;++i )
		onRecv_3_M_DP_NA_1(rf.getTransCause(),rf.getInfoAddr_3_M_DP_NA_1(i),*rf.getInfo_3_M_DP_NA_1(i),ts,rts);

	return Action_Nothing;
}

/**
 * 离散量
 * @param rf
 * @param tf
 * @return
 */
CIec104Master::EAction CIec104Master::dealAsdu_M_ME_NB_1( const frame_apdu_t& rf,frame_apdu_t& /*tf*/,const ts_t& ts,const rts_t& rts ){
	dm::uint8 count = rf.getElementsCount();
	for( dm::uint8 i=0;i<count;++i )
		onRecv_11_M_ME_NB_1(rf.getTransCause(),rf.getInfoAddr_11_M_ME_NB_1(i),*rf.getInfo_11_M_ME_NB_1(i),*rf.getInfo_11_M_ME_NB_1_qds(i),ts,rts);

	return Action_Nothing;
}

/**
 * 测量量
 * @param rf
 * @param tf
 * @return
 */
CIec104Master::EAction CIec104Master::dealAsdu_M_ME_NC_1( const frame_apdu_t& rf,frame_apdu_t& /*tf*/,const ts_t& ts,const rts_t& rts ){
	dm::uint8 count = rf.getElementsCount();
	for( dm::uint8 i=0;i<count;++i )
		onRecv_13_M_ME_NC_1(rf.getTransCause(),rf.getInfoAddr_13_M_ME_NC_1(i),*rf.getInfo_13_M_ME_NC_1(i),*rf.getInfo_13_M_ME_NC_1_qds(i),ts,rts);

	return Action_Nothing;
}

/**
 * 累计量
 * @param rf
 * @param tf
 * @return
 */
CIec104Master::EAction CIec104Master::dealAsdu_M_IT_NA_1( const frame_apdu_t& rf,frame_apdu_t& /*tf*/,const ts_t& ts,const rts_t& rts ){
	dm::uint8 count = rf.getElementsCount();
	for( dm::uint8 i=0;i<count;++i )
		onRecv_15_M_IT_NA_1(rf.getTransCause(),rf.getInfoAddr_15_M_IT_NA_1(i),rf.getInfo_15_M_IT_NA_1(i)->bits.counterReading,ts,rts);

	return Action_Nothing;
}

/**
 * 时标状态量
 * @param rf
 * @param tf
 * @return
 */
CIec104Master::EAction CIec104Master::dealAsdu_M_DP_TB_1( const frame_apdu_t& rf,frame_apdu_t& /*tf*/,const ts_t& ts,const rts_t& rts ){
	dm::uint8 count = rf.getElementsCount();
	for( dm::uint8 i=0;i<count;++i )
		onRecv_31_M_DP_TB_1(rf.getTransCause(),rf.getInfoAddr_31_M_DP_TB_1(i),*rf.getInfo_31_M_DP_TB_1_qid(i),*rf.getInfo_31_M_DP_TB_1_time(i),ts,rts );

	return Action_Nothing;
}

/**
 * 时标离散量
 * @param rf
 * @param tf
 * @return
 */
CIec104Master::EAction CIec104Master::dealAsdu_M_ME_TE_1( const frame_apdu_t& rf,frame_apdu_t& /*tf*/,const ts_t& ts,const rts_t& rts ){
	dm::uint8 count = rf.getElementsCount();
	for( dm::uint8 i=0;i<count;++i )
		onRecv_35_M_ME_TE_1(rf.getTransCause(),rf.getInfoAddr_35_M_ME_TE_1(i),*rf.getInfo_35_M_ME_TE_1_sva(i),*rf.getInfo_35_M_ME_TE_1_qds(i),*rf.getInfo_35_M_ME_TE_1_time(i),ts,rts);

	return Action_Nothing;
}

/**
 * 时标测量量
 * @param rf
 * @param tf
 * @return
 */
CIec104Master::EAction CIec104Master::dealAsdu_M_ME_TF_1( const frame_apdu_t& rf,frame_apdu_t& /*tf*/,const ts_t& ts,const rts_t& rts ){
	dm::uint8 count = rf.getElementsCount();
	for( dm::uint8 i=0;i<count;++i )
		onRecv_36_M_ME_TF_1(rf.getTransCause(),rf.getInfoAddr_36_M_ME_TF_1(i),*rf.getInfo_36_M_ME_TF_1_std(i),*rf.getInfo_36_M_ME_TF_1_qds(i),*rf.getInfo_36_M_ME_TF_1_time(i),ts,rts);

	return Action_Nothing;
}

/**
 * 时标累计量
 * @param rf
 * @param tf
 * @return
 */
CIec104Master::EAction CIec104Master::dealAsdu_M_IT_TB_1( const frame_apdu_t& rf,frame_apdu_t& /*tf*/,const ts_t& ts,const rts_t& rts ){
	dm::uint8 count = rf.getElementsCount();
	for( dm::uint8 i=0;i<count;++i )
		onRecv_37_M_IT_TB_1(rf.getTransCause(),rf.getInfoAddr_37_M_IT_TB_1(i),rf.getInfo_37_M_IT_TB_1_bcr(i)->bits.counterReading,*rf.getInfo_37_M_IT_TB_1_time(i),ts,rts);

	return Action_Nothing;
}

/**
 * 召唤命令返回
 * @param rf
 * @param
 * @return
 */
CIec104Master::EAction CIec104Master::dealAsdu_C_IC_NA_1( const frame_apdu_t& rf,frame_apdu_t& /*tf*/,const ts_t& ts,const rts_t& rts ){
	switch( rf.getTransCause() ){
	case frame_apdu_t::FACause_actcon:
		if( m_taskCall!=Started )
			log().warnning(THISMODULE "当前并非召唤任务已启动");
		// 激活确认
		break;
	case frame_apdu_t::FACause_actterm:
		if( m_taskCall!=Started ){
			log().warnning(THISMODULE "当前没有正确执行的召唤任务");
			return Action_Nothing;
		}
		// 激活中止
		endTask_call(ts,rts,Success);
		break;
	default:
		endTask_call(ts,rts,Fail);
		break;
	}

	return Action_Nothing;
}

/**
 * 对时命令返回
 * @param rf
 * @param
 * @return
 */
CIec104Master::EAction CIec104Master::dealAsdu_C_CS_NA_1( const frame_apdu_t& rf,frame_apdu_t& /*tf*/,const ts_t& ts,const rts_t& rts ){
	switch( rf.getTransCause() ){
	case frame_apdu_t::FACause_actcon:
		// 激活确认
		break;
	case frame_apdu_t::FACause_actterm:
		// 激活中止
		endTask_syncClock(ts,rts,Success);
		break;
	default:
		endTask_syncClock(ts,rts,Fail);
		break;
	}

	return Action_Nothing;
}

/**
 * 远控返回
 * @param rf
 * @param
 * @return
 */
CIec104Master::EAction CIec104Master::dealAsdu_C_DC_NA_1( const frame_apdu_t& rf,frame_apdu_t& /*tf*/,const ts_t& /*ts*/,const rts_t& /*rts*/ ){
	switch( rf.getTransCause() ){
	case frame_apdu_t::FACause_actcon:
		// 激活确认
		break;
	case frame_apdu_t::FACause_actterm:
		// 激活终止
		m_taskCall = Success;
		break;
	default:
		m_taskCall = Fail;
	}

	return Action_Nothing;
}

/**
 * 读参数返回
 * @param rf
 * @param
 * @return
 */
CIec104Master::EAction CIec104Master::dealAsdu_C_RD_NA_1( const frame_apdu_t& rf,frame_apdu_t& /*tf*/,const ts_t& ts,const rts_t& rts ){
	switch( rf.getTransCause() ){
	case frame_apdu_t::FACause_req:
		// 请求或者被请求
		break;
	default:
		endTask_paraGetUint8(ts,rts,Fail);
	}

	return Action_Nothing;
}

/**
 * 参数写返回
 * @param rf
 * @param
 * @return
 */
CIec104Master::EAction CIec104Master::dealAsdu_C_SE_NB_1( const frame_apdu_t& rf,frame_apdu_t& /*tf*/,const ts_t& ts,const rts_t& rts ){
	switch( rf.getTransCause() ){
	case frame_apdu_t::FACause_actcon:
		// 激活确认
		break;
	case frame_apdu_t::FACause_actterm:
		// 激活终止
		endTask_paraSet(ts,rts,Success);
		break;
	default:
		endTask_paraSet(ts,rts,Fail);
	}

	return Action_Nothing;
}

/**
 * 读取参数返回值
 * @param rf
 * @param
 * @return
 */
CIec104Master::EAction CIec104Master::dealAsdu_P_ME_NB_1( const frame_apdu_t& rf,frame_apdu_t& /*tf*/,const ts_t& ts,const rts_t& rts ){
	onRecv_111_P_ME_NA_1(rf.getTransCause(),rf.getInfoAddr_111_P_ME_NB_1(),*rf.getInfo_111_P_ME_NB_1_sva(),*rf.getInfo_111_P_ME_NB_1_qpm(),ts,rts);

	return Action_Nothing;
}

// 双点信息
bool CIec104Master::onRecv_3_M_DP_NA_1( const frame_apdu_t::ECause& /*cause*/,const dm::uint32& address,const frame_apdu_t::UDiq& diq,const ts_t& /*ts*/,const rts_t& /*rts*/ ){
	log().info( THISMODULE "子类未处理：%d:%d",address,diq.bits.dpi);
	return false;
}

bool CIec104Master::onRecv_31_M_DP_TB_1( const frame_apdu_t::ECause& /*cause*/,const dm::uint32& address,const frame_apdu_t::UDiq& diq,const frame_apdu_t::UCp56Time2a& time,const ts_t& /*ts*/,const rts_t& /*rts*/ ){
	log().info( THISMODULE "子类未处理：%d:%d %d-%d-%d %d:%d:%d",address,diq.bits.dpi,time.bits.year,time.bits.mon,time.bits.day,time.bits.hour,time.bits.min,time.bits.ms);
	return false;
}

// 标度化值
bool CIec104Master::onRecv_11_M_ME_NB_1( const frame_apdu_t::ECause& /*cause*/,const dm::uint32& /*address*/,const frame_apdu_t::USva& /*nva*/,const frame_apdu_t::UQds& /*qds*/,const ts_t& /*ts*/,const rts_t& /*rts*/ ){
	return false;
}

bool CIec104Master::onRecv_35_M_ME_TE_1( const frame_apdu_t::ECause& /*cause*/,const dm::uint32& /*address*/,const frame_apdu_t::USva& /*nva*/,const frame_apdu_t::UQds& /*qds*/,const frame_apdu_t::UCp56Time2a& /*time*/,const ts_t& /*ts*/,const rts_t& /*rts*/ ){
	return false;
}


// 短浮点数
bool CIec104Master::onRecv_13_M_ME_NC_1( const frame_apdu_t::ECause& /*cause*/,const dm::uint32& /*address*/,const frame_apdu_t::UStd& /*frac*/,const frame_apdu_t::UQds& /*qds*/,const ts_t& /*ts*/,const rts_t& /*rts*/ ){
	return false;
}

bool CIec104Master::onRecv_36_M_ME_TF_1( const frame_apdu_t::ECause& /*cause*/,const dm::uint32& /*address*/,const frame_apdu_t::UStd& /*frac*/,const frame_apdu_t::UQds& /*qds*/,const frame_apdu_t::UCp56Time2a& /*time*/,const ts_t& /*ts*/,const rts_t& /*rts*/ ){
	return false;
}

// 累计量
bool CIec104Master::onRecv_15_M_IT_NA_1( const frame_apdu_t::ECause& /*cause*/,const dm::uint32& /*address*/,const dm::int32& /*value*/,const ts_t& /*ts*/,const rts_t& /*rts*/ ){
	return false;
}

bool CIec104Master::onRecv_37_M_IT_TB_1( const frame_apdu_t::ECause& /*cause*/,const dm::uint32& /*address*/,const dm::int32& /*value*/,const frame_apdu_t::UCp56Time2a& /*time*/,const ts_t& /*ts*/,const rts_t& /*rts*/ ){
	return false;
}

// 测量值参数 标度化值
bool CIec104Master::onRecv_111_P_ME_NA_1( const frame_apdu_t::ECause& /*cause*/,const dm::uint32& /*address*/,const frame_apdu_t::USva& /*sva*/,const frame_apdu_t::UQpm& /*qpm*/,const ts_t& /*ts*/,const rts_t& /*rts*/ ){
	return false;
}


CIec104Master::EAction CIec104Master::taskStart_call( const ts_t& /*ts*/,const rts_t& /*rts*/ ){
	txFrame().getApdu().makeFrame_100_C_IC_NA_1( m_callGroup+20 );
	txFrame().getApdu().setCommonAddress(m_commonAddr);

	m_taskCall = Started;

	return Action_SendAndReTime;
}

CIec104Master::EAction CIec104Master::taskDo_call( const ts_t& /*ts*/,const rts_t& /*rts*/ ){
	return Action_Nothing;
}

CIec104Master::EAction CIec104Master::taskStart_syncClock( const ts_t& /*ts*/,const rts_t& /*rts*/ ){
	frame_apdu_t::UCp56Time2a n;
	getCurrentTime(n);

	txFrame().getApdu().makeFrame_103_C_CS_NA_1(n);

	m_taskClock = Started;

	return Action_SendAndReTime;
}

CIec104Master::EAction CIec104Master::taskDo_syncClock( const ts_t& /*ts*/,const rts_t& /*rts*/ ){
	return Action_Nothing;
}

CIec104Master::EAction CIec104Master::taskStart_remoteControl( const ts_t& /*ts*/,const rts_t& /*rts*/ ){
	txFrame().getApdu().makeFrame_46_C_DC_NA_1( m_rmtctlIndex,
			m_rmtctl==dm::msg::Rc_Close||m_rmtctl==dm::msg::Rc_PreClose,
			m_rmtctl==dm::msg::Rc_PreClose||m_rmtctl==dm::msg::Rc_PreOpen );

	m_taskRmtCtl = Started;

	return Action_SendAndReTime;
}

CIec104Master::EAction CIec104Master::taskDo_remoteControl( const ts_t& /*ts*/,const rts_t& /*rts*/ ){
	return Action_Nothing;
}

CIec104Master::EAction CIec104Master::taskStart_parameters( const ts_t& /*ts*/,const rts_t& /*rts*/ ){
	if( m_paraSet ){
		txFrame().getApdu().makeFrame_102_C_RD_NA_1(m_paraData.index);
	}else{
		txFrame().getApdu().makeFrame_48_C_SE_NA_1((unsigned int)m_paraData.index,m_paraData.as_uint16()[0]);
	}

	m_taskParas = Started;

	return Action_SendAndReTime;
}

CIec104Master::EAction CIec104Master::taskDo_parameters( const ts_t& /*ts*/,const rts_t& /*rts*/ ){
	return Action_Nothing;
}

}
}

